/******************************************************************************* 
 * Copyright (c) 2008 xored software, Inc.  
 * 
 * All rights reserved. This program and the accompanying materials 
 * are made available under the terms of the Eclipse Public License v1.0 
 * which accompanies this distribution, and is available at 
 * http://www.eclipse.org/legal/epl-v10.html  
 * 
 * Contributors: 
 *     xored software, Inc. - initial API and Implementation (Yuri Strot) 
 *******************************************************************************/
package com.xored.glance.ui.controls.tree;

import java.util.ArrayList;
import java.util.List;

import org.eclipse.swt.events.TreeEvent;
import org.eclipse.swt.events.TreeListener;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;

import com.xored.glance.ui.controls.items.ItemCell;
import com.xored.glance.ui.controls.items.ItemProvider;
import com.xored.glance.ui.controls.items.ItemSource;
import com.xored.glance.ui.sources.SourceSelection;

/**
 * @author Yuri Strot
 * 
 */
public class TreeSource extends ItemSource implements TreeListener {

	public TreeSource(Tree tree) {
		super(tree);
		tree.addSelectionListener(this);
		tree.addTreeListener(this);
	}

	@Override
	public Tree getControl() {
		return (Tree) super.getControl();
	}

	@Override
	public void dispose() {
		getControl().removeSelectionListener(this);
		getControl().removeTreeListener(this);
		super.dispose();
	}

	public SourceSelection getSelection() {
		TreeItem[] items = getControl().getSelection();
		if (items.length > 0) {
			List<ItemCell> cells = getCells();
			for (ItemCell cell : cells) {
				if (cell.getItem().equals(items[0])) {
					return new SourceSelection(cell, 0, cell.getText().length());
				}
			}
		}
		return null;
	}

	@Override
	protected void collectCells(List<ItemCell> cells) {
		collectCells(cells, getControl().getItems());
	}

	private void collectCells(List<ItemCell> cells, TreeItem[] items) {
		if (items.length > 0) {
			int columns = items[0].getParent().getColumnCount();
			if (columns == 0)
				columns = 1;
			for (TreeItem item : items) {
				for (int j = 0; j < columns; j++) {
					cells.add(new ItemCell(item, j, getItemProvider()));
				}
				if (item.getExpanded())
					collectCells(cells, item.getItems());
			}
		}
	}

	public void treeCollapsed(TreeEvent event) {
		if (event.item instanceof TreeItem) {
			List<ItemCell> cells = new ArrayList<ItemCell>();
			collectCells(cells, ((TreeItem) event.item).getItems());
			decorator.blocksChanged(cells.toArray(new ItemCell[cells.size()]),
					new ItemCell[0]);
		}
	}

	public void treeExpanded(TreeEvent event) {
		if (event.item instanceof TreeItem) {
			List<ItemCell> cells = new ArrayList<ItemCell>();
			collectCells(cells, ((TreeItem) event.item).getItems());
			decorator.blocksChanged(new ItemCell[0], cells
					.toArray(new ItemCell[cells.size()]));
		}
	}

	@Override
	protected ItemProvider getItemProvider() {
		return TreeItemProvider.getInstance();
	}

}
